﻿using CSRedis;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace B.S.BaseData.Infrastructure.Helper
{
    /// <summary>
    /// Redis缓存辅助类
    /// </summary>
    public class RedisHelpers
    {
        private readonly CSRedisClient _redisClient;
        private readonly TimeSpan _defaultExpiry = TimeSpan.FromMinutes(30); // 默认过期时间30分钟

        public RedisHelpers(CSRedisClient redisClient)
        {
            _redisClient = redisClient;
        }

        /// <summary>
        /// 获取或设置缓存
        /// </summary>
        /// <typeparam name="T">缓存数据类型</typeparam>
        /// <param name="key">缓存键</param>
        /// <param name="func">获取数据的方法</param>
        /// <param name="expiry">过期时间</param>
        /// <returns>缓存的数据</returns>
        public async Task<T> GetOrSetAsync<T>(string key, Func<Task<T>> func, TimeSpan? expiry = null)
        {
            // 检查Redis缓存中是否存在数据
            var cachedData = await _redisClient.GetAsync(key);

            if (!string.IsNullOrEmpty(cachedData))
            {
                // 如果redis中有数据，直接返回缓存数据（反序列化）
                var cachedResult = JsonConvert.DeserializeObject<T>(cachedData);
                if (cachedResult != null)
                {
                    return cachedResult;
                }
            }

            // 如果redis中没有数据，执行func方法获取数据
            var result = await func();

            if (result != null)
            {
                // 缓存到redis
                await _redisClient.SetAsync(key, JsonConvert.SerializeObject(result), expiry ?? _defaultExpiry);
            }

            return result;
        }
        
        /// <summary>
        /// 删除缓存
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <returns>是否删除成功</returns>
        public async Task<bool> DeleteAsync(string key)
        {
            return await _redisClient.DelAsync(key) > 0;
        }
        
        /// <summary>
        /// 判断缓存是否存在
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <returns>是否存在</returns>
        public async Task<bool> ExistsAsync(string key)
        {
            return await _redisClient.ExistsAsync(key);
        }
    }
}
